package com.meiyuetao.myt.md.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

import lab.s2jh.core.annotation.MetaData;
import lab.s2jh.core.entity.annotation.SkipParamBind;
import lab.s2jh.core.web.json.DateTimeJsonSerializer;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Type;
import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.collect.Lists;
import com.meiyuetao.myt.c2c.entity.C2cShopInfo;
import com.meiyuetao.myt.core.entity.MytBaseEntity;
import com.meiyuetao.myt.partner.entity.Partner;
import com.meiyuetao.myt.stock.entity.StorageLocation;
import com.meiyuetao.myt.vip.entity.VipCommodity;
import com.meiyuetao.myt.vip.entity.VipCommodityRate;

@MetaData("商品")
@Entity
@Table(name = "iyb_commodity")
@Cache(usage = CacheConcurrencyStrategy.NONE)
@Audited
public class Commodity extends MytBaseEntity {
    private static final long serialVersionUID = -4390996382259329769L;
    /** 推荐号标识：标记删除 */
    public static final Integer RANK_MARK_DELETE = -9999;
    /** 推荐号标识：接口创建待审核编辑 */
    public static final Integer RANK_API_TBD = 1000;
    /** 橱窗图数量 */
    private Integer picCount = 0;
    private Integer recommendRank = 100;
    /** 购买人数 */
    private Integer boughtCount = 0;
    /** 消费码顺延过期天数,如60天有效期 */
    private Integer purchaseCodeExpiredDays;
    /** 自定义盒子长度 */
    private Integer diyBoxLength;
    /** 自定义盒子宽度 */
    private Integer diyBoxWidth;
    /** 自定义盒子高度 */
    private Integer diyBoxHeight;
    /** 每个用户单日可购买量 ,默认为0 */
    private Integer dailyUserCanBuy = 20;
    private Integer customerValueLimited = 0;

    /** 浏览次数，可以作为人气值 */
    private Long viewCount = 0L;
    /** 喜爱数 */
    private Long loveCount = 0L;

    // Date
    /** 消费码固定过期日期,如2013-3-20,包含当天有效 */
    private Date purchaseCodeExpiredDatetime;
    private Date auditDate;
    /** 最后发货时间， */
    private Date lastDeliveryTime;
    /** 最后采购时间 */
    private Date lastPurchaseTime;

    // Boolean
    private Boolean needShowUrl = Boolean.TRUE;
    /** 是否生成消费码 */
    private Boolean genPurchaseCodeFlag;
    /** 是否支持自定义 */
    private Boolean diyEnableDesign;
    /** 是否优品 */
    private Boolean preferred = Boolean.FALSE;
    private Boolean canBuyNow = Boolean.TRUE;
    @MetaData("普通购买是否有赠品")
    private Boolean normalPresent = Boolean.FALSE;
    @MetaData("周期购是否有赠品")
    private Boolean circlePresent = Boolean.FALSE;
    @MetaData("是否允许超卖")
    private Boolean allowOversold = Boolean.FALSE;
    /** 是否周期购 */
    private Boolean circle = Boolean.FALSE;
    /** 是否积分商城首页显示 */
    private Boolean coinPageShow = Boolean.FALSE;

    // String
    /** 自建条码（或者说叫商品唯一编号） */
    private String sku;
    private String title;
    private String subTitle;
    private String smallPic;
    private String showUrl;
    private String showUrl2;
    private String showUrl3;
    private String taobaoNumIid;
    private String taobaoNumIid2;
    private String taobaoNumIid3;
    private String measureUnit;
    private String keywords;
    private String timelines;
    private String shortUrl;
    private String specification;
    private String detail;
    private String guide;
    private String packList;
    private String support;
    @MetaData("运送地")
    private String regions = "";
    @MetaData("运送地Ids")
    private String regionsId = null;
    /** 促销样式Key，对应数据字典 */
    private String promoStyleKey;
    /** （未定义时）价格计划规则：LAST=取最后最近价格计划，MAX=取最低价最高价格计划，OFF=下架 */
    private String undefinePricePlanRule;
    /** 商品来源,标识是红孩子/京东/自有等 */
    private String source = "IYOUBOX";
    /** 商品来源URL */
    private String sourceUrl;
    /** 商品来源唯一编号 */
    private String sourceUid;
    /** 商品实际的条码，用于条码枪扫描录入的条码号 */
    private String barcode;
    /** 自定义最大数 */
    private String diyMaxSettleCount;
    /** 自定义图片 */
    private String diyShowPic;
    /** 温馨提示 */
    private String prompt;
    /** 最后采购订单凭证号 */
    private String lastPurchaseSN;
    /** 此商品在京东上的sku_id */
    private String jdSku;
    @MetaData("天猫SKU")
    private String tmallSku;
    @MetaData(value = "周期购标题")
    private String circleTitle;
    @MetaData(value = "周期购描述", comments = "HTML文本")
    private String circleSpecification;
    @MetaData("规格型号")
    private String spec;
    @MetaData("erp规格")
    private String erpSpec;
    @MetaData("ERP商品ID")
    private String erpProductId;
    @MetaData("比价链接")
    private String priceCompareUrl;
    private String taxCode;
    @MetaData("备注")
    private String memo;
    private String auditExplain;
    private String audityUser;
    /** 最后发货凭证号 */
    private String lastDeliverySN;
    @MetaData("横幅图")
    private String bannerPic;

    // BigDecimal
    /** 哎呦价格 */
    private BigDecimal price;
    /** 采购成本价格 */
    private BigDecimal costPrice;
    private BigDecimal marketPrice;
    private BigDecimal netPrice;
    private BigDecimal vipPrice;
    /** 库存报警阀值 */
    private BigDecimal stockThresholdQuantity = BigDecimal.ZERO;
    /** 汇总库存数量 */
    private BigDecimal stockTotalQuantity = BigDecimal.ZERO;
    /** 正在采购中的数量 */
    private BigDecimal purchasingTotalQuantity = BigDecimal.ZERO;
    /** 总计实际库存 */
    private BigDecimal totalRealStockCount = BigDecimal.ZERO;
    /** 总计冻结库存 */
    private BigDecimal totalFreezedStockCount = BigDecimal.ZERO;
    /** 可售库存 */
    private BigDecimal canSaleCount = new BigDecimal(200);
    /** 佣金率 */
    private BigDecimal commissionRate;
    /** 当日已售出数量 ,默认为0 */
    private BigDecimal dailySoldCount = BigDecimal.ZERO;
    /** 周期购价格 */
    private BigDecimal circlePrice;
    /** 商品重量，单位kg */
    private BigDecimal weight;
    @MetaData("周期购最小购买数量")
    private BigDecimal circleMinQuantity = new BigDecimal(2);
    @MetaData("佣金比例")
    private BigDecimal rewardRate;
    @MetaData("比价偏移比率")
    private BigDecimal priceCompareRate;
    @MetaData("积分")
    private BigDecimal coins;
    @MetaData("返还积分")
    private BigDecimal backCoins;

    // Entity
    /** 默认库存地 */
    private StorageLocation defaultStorageLocation;
    /** 商品关联分类集合 */
    private Category category;
    /** 商品所属合作伙伴 */
    private Partner partner;
    @MetaData("供应商")
    private Partner provider;
    /** 商品关联图片集合 */
    private List<CommodityPic> commodityPics = Lists.newArrayList();
    /** 商品关联价格计划集合 */
    private List<CommodityPrice> commodityPrices = Lists.newArrayList();
    /** 商品关联价格计划集合 */
    private List<CommodityPricePlan> commodityPricePlans = Lists.newArrayList();
    @MetaData("租借商品价格表")
    private List<CommodityRentalPrice> commodityRentalPrice = Lists.newArrayList();
    /** 关联外部商品 */
    private List<CommoditySkuRelation> commoditySkuRelations = Lists.newArrayList();
    /** 商品所属分组 */
    private CommodityGroup commodityGroup;
    private List<CommodityComment> commodityComments;
    private CommodityVaryPrice commodityVaryPrice;
    private VipCommodity vipCommodity;
    private List<CommodityR2Ptcategory> commodityR2Ptcategories = new ArrayList<CommodityR2Ptcategory>();
    private List<CommoditySaleDateCount> commoditySaleDateCounts = new ArrayList<CommoditySaleDateCount>();
    @MetaData("360跨境信息")
    private KjCommodityInfo kjCommodityInfo;
    private List<VipCommodityRate> vipCommodityRates = new ArrayList<VipCommodityRate>();
    // private List<WlfCommodityR2PartTime> wlfCommodityR2PartTimes = new
    // ArrayList<WlfCommodityR2PartTime>();
    @MetaData("美月淘集市店铺")
    private C2cShopInfo c2cShopInfo;
    @MetaData("商品销售区域")
    private Set<CommodityDistributRegion> commodityDistributRegion = new HashSet<CommodityDistributRegion>();
    private Brand brand;

    // Enum
    /**
     * 消费码过期规则：FIXED：固定过期日期(purchaseCodeExpiredDatetime设定值)，POSTPONE：顺延固定天数(确认日期
     * +purchaseCodeExpiredDays)
     */
    private PurchaseCodeExpireRuleEnum purchaseCodeExpireRule;
    private CommodityStatusEnum commodityStatus = CommodityStatusEnum.S40OFFSALE;
    private CommodityAuditStatusEnum commodityAuditStatus = CommodityAuditStatusEnum.A10UNSUBMIT;
    @MetaData("网站过滤")
    private SolrFilterTypeEnum solrFilterType = SolrFilterTypeEnum.MYT;
    private CommodityTypeEnum commodityType = CommodityTypeEnum.GOODS;

    public enum CommodityTypeEnum {
        @MetaData(value = "普通商品")
        GOODS,

        @MetaData(value = "服务")
        SERVICE,

        @MetaData(value = "租赁商品")
        RENTAL;
    }

    public enum PurchaseCodeExpireRuleEnum {

        @MetaData(value = "固定过期日期")
        FIXED,

        @MetaData(value = "顺延固定天数")
        POSTPONE;
    }

    public enum CommodityAuditStatusEnum {

        @MetaData(value = "未审批")
        A10UNSUBMIT,

        @MetaData(value = "审批驳回")
        A20REJECTED,

        @MetaData(value = "审批通过")
        A30PASSED;
    }

    public enum CommodityStatusEnum {
        @MetaData("在售")
        S30ONSALE,

        @MetaData("下架")
        S40OFFSALE,

        @MetaData("删除")
        S50DELETE,

        @MetaData("导入")
        S60IMPORT;
    }

    public enum SolrFilterTypeEnum {
        @MetaData(value = "美月淘网站")
        MYT,

        @MetaData(value = "优蜜美店")
        LM,

        @MetaData("附近店铺")
        SHOP;
    }

    public Boolean getCanBuyNow() {
        return canBuyNow;
    }

    public void setCanBuyNow(Boolean canBuyNow) {
        this.canBuyNow = canBuyNow;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 16)
    @JsonProperty
    public CommodityStatusEnum getCommodityStatus() {
        return commodityStatus;
    }

    public void setCommodityStatus(CommodityStatusEnum commodityStatus) {
        this.commodityStatus = commodityStatus;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @OrderBy("picIndex desc")
    @NotAudited
    public List<CommodityPic> getCommodityPics() {
        return commodityPics;
    }

    public void setCommodityPics(List<CommodityPic> commodityPics) {
        this.commodityPics = commodityPics;
    }

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommodityPrice> getCommodityPrices() {
        return commodityPrices;
    }

    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "kj_commodity_info_sid")
    @NotAudited
    public KjCommodityInfo getKjCommodityInfo() {
        return kjCommodityInfo;
    }

    public void setKjCommodityInfo(KjCommodityInfo kjCommodityInfo) {
        this.kjCommodityInfo = kjCommodityInfo;
    }

    public void setCommodityPrices(List<CommodityPrice> commodityPrices) {
        this.commodityPrices = commodityPrices;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommodityPricePlan> getCommodityPricePlans() {
        return commodityPricePlans;
    }

    public void setCommodityPricePlans(List<CommodityPricePlan> commodityPricePlans) {
        this.commodityPricePlans = commodityPricePlans;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommodityRentalPrice> getCommodityRentalPrice() {
        return commodityRentalPrice;
    }

    public void setCommodityRentalPrice(List<CommodityRentalPrice> commodityRentalPrice) {
        this.commodityRentalPrice = commodityRentalPrice;
    }
    @ManyToOne
    @JoinColumn(name = "commodity_group_sid")
    @NotAudited
    public CommodityGroup getCommodityGroup() {
        return commodityGroup;
    }

    public void setCommodityGroup(CommodityGroup commodityGroup) {
        this.commodityGroup = commodityGroup;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 64)
    @JsonProperty
    public CommodityAuditStatusEnum getCommodityAuditStatus() {
        return commodityAuditStatus;
    }

    public void setCommodityAuditStatus(CommodityAuditStatusEnum commodityAuditStatus) {
        this.commodityAuditStatus = commodityAuditStatus;
    }

    public String getAuditExplain() {
        return auditExplain;
    }

    public void setAuditExplain(String auditExplain) {
        this.auditExplain = auditExplain;
    }

    public Date getAuditDate() {
        return auditDate;
    }

    public void setAuditDate(Date auditDate) {
        this.auditDate = auditDate;
    }

    public String getAudityUser() {
        return audityUser;
    }

    public void setAudityUser(String audityUser) {
        this.audityUser = audityUser;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommodityComment> getCommodityComments() {
        return commodityComments;
    }

    public void setCommodityComments(List<CommodityComment> commodityComments) {
        this.commodityComments = commodityComments;
    }

    public String getTmallSku() {
        return tmallSku;
    }

    public void setTmallSku(String tmallSku) {
        this.tmallSku = tmallSku;
    }

    public Date getLastDeliveryTime() {
        return lastDeliveryTime;
    }

    public void setLastDeliveryTime(Date lastDeliveryTime) {
        this.lastDeliveryTime = lastDeliveryTime;
    }

    public String getLastDeliverySN() {
        return lastDeliverySN;
    }

    public void setLastDeliverySN(String lastDeliverySN) {
        this.lastDeliverySN = lastDeliverySN;
    }

    @JsonProperty
    public String getBannerPic() {
        return bannerPic;
    }

    public void setBannerPic(String bannerPic) {
        this.bannerPic = bannerPic;
    }

    public Date getLastPurchaseTime() {
        return lastPurchaseTime;
    }

    public void setLastPurchaseTime(Date lastPurchaseTime) {
        this.lastPurchaseTime = lastPurchaseTime;
    }

    public String getLastPurchaseSN() {
        return lastPurchaseSN;
    }

    public void setLastPurchaseSN(String lastPurchaseSN) {
        this.lastPurchaseSN = lastPurchaseSN;
    }

    @Column(length = 128, nullable = false)
    @JsonProperty
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Column(precision = 18, scale = 2, nullable = false)
    @JsonProperty
    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    @Column(precision = 18, scale = 2, nullable = false)
    @JsonProperty
    public BigDecimal getMarketPrice() {
        return marketPrice;
    }

    public void setMarketPrice(BigDecimal marketPrice) {
        this.marketPrice = marketPrice;
    }

    @Column(length = 1024, nullable = true)
    @JsonProperty
    public String getShowUrl() {
        return showUrl;
    }

    public void setShowUrl(String showUrl) {
        this.showUrl = showUrl;
    }

    @Column(length = 128, unique = true, nullable = false, name = "barcode")
    @JsonProperty
    public String getSku() {
        return sku;
    }

    public void setSku(String sku) {
        this.sku = sku;
    }

    @Column(length = 128)
    @JsonProperty
    public String getSmallPic() {
        return smallPic;
    }

    public void setSmallPic(String smallPic) {
        this.smallPic = smallPic;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getSpecification() {
        return specification;
    }

    public void setSpecification(String specification) {
        this.specification = specification;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getGuide() {
        return guide;
    }

    public void setGuide(String guide) {
        this.guide = guide;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getPackList() {
        return packList;
    }

    public void setPackList(String packList) {
        this.packList = packList;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getSupport() {
        return support;
    }

    public void setSupport(String support) {
        this.support = support;
    }

    @OneToOne(cascade = CascadeType.DETACH, optional = true)
    @JoinColumn(name = "brand_SID")
    @NotAudited
    @JsonProperty
    public Brand getBrand() {
        return brand;
    }

    public void setBrand(Brand brand) {
        this.brand = brand;
    }

    public Integer getPicCount() {
        return picCount;
    }

    public void setPicCount(Integer picCount) {
        this.picCount = picCount;
    }

    @Column(length = 1024, nullable = true)
    public String getShowUrl2() {
        return showUrl2;
    }

    public void setShowUrl2(String showUrl2) {
        this.showUrl2 = showUrl2;
    }

    @Column(length = 1024, nullable = true)
    public String getShowUrl3() {
        return showUrl3;
    }

    public void setShowUrl3(String showUrl3) {
        this.showUrl3 = showUrl3;
    }

    @Column(length = 128, nullable = true)
    public String getTaobaoNumIid() {
        return taobaoNumIid;
    }

    public void setTaobaoNumIid(String taobaoNumIid) {
        this.taobaoNumIid = taobaoNumIid;
    }

    @Column(length = 128, nullable = true)
    public String getTaobaoNumIid2() {
        return taobaoNumIid2;
    }

    public void setTaobaoNumIid2(String taobaoNumIid2) {
        this.taobaoNumIid2 = taobaoNumIid2;
    }

    @Column(length = 128, nullable = true)
    public String getTaobaoNumIid3() {
        return taobaoNumIid3;
    }

    public void setTaobaoNumIid3(String taobaoNumIid3) {
        this.taobaoNumIid3 = taobaoNumIid3;
    }

    @Type(type = "yes_no")
    public Boolean getNeedShowUrl() {
        return needShowUrl;
    }

    public void setNeedShowUrl(Boolean needShowUrl) {
        this.needShowUrl = needShowUrl;
    }

    @Column(length = 32)
    @JsonProperty
    public String getMeasureUnit() {
        return measureUnit;
    }

    public void setMeasureUnit(String measureUnit) {
        this.measureUnit = measureUnit;
    }

    @Column(name = "stock_threshold_quantity", precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getStockThresholdQuantity() {
        return stockThresholdQuantity;
    }

    public void setStockThresholdQuantity(BigDecimal stockThresholdQuantity) {
        this.stockThresholdQuantity = stockThresholdQuantity;
    }

    @Column(name = "stock_total_quantity", precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getStockTotalQuantity() {
        return stockTotalQuantity;
    }

    public void setStockTotalQuantity(BigDecimal stockTotalQuantity) {
        this.stockTotalQuantity = stockTotalQuantity;
    }

    @OneToOne(cascade = CascadeType.DETACH)
    @JoinColumn(name = "Default_Storage_Location_SID")
    @NotAudited
    @JsonProperty
    public StorageLocation getDefaultStorageLocation() {
        return defaultStorageLocation;
    }

    public void setDefaultStorageLocation(StorageLocation defaultStorageLocation) {
        this.defaultStorageLocation = defaultStorageLocation;
    }

    @Column(precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getNetPrice() {
        return netPrice;
    }

    public void setNetPrice(BigDecimal netPrice) {
        this.netPrice = netPrice;
    }

    @Column(length = 512)
    @JsonProperty
    public String getKeywords() {
        return keywords;
    }

    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    @Column(length = 64)
    @JsonProperty
    public String getShortUrl() {
        return shortUrl;
    }

    public void setShortUrl(String shortUrl) {
        this.shortUrl = shortUrl;
    }

    @Column(name = "rank")
    @JsonProperty
    public Integer getRecommendRank() {
        return recommendRank;
    }

    public void setRecommendRank(Integer recommendRank) {
        this.recommendRank = recommendRank;
    }

    @Transient
    @JsonProperty
    public String getDisplay() {
        return this.getSku() + " " + this.getTitle();
    }

    public Integer getBoughtCount() {
        return boughtCount;
    }

    public void setBoughtCount(Integer boughtCount) {
        this.boughtCount = boughtCount;
    }

    public Long getViewCount() {
        return viewCount;
    }

    public void setViewCount(Long viewCount) {
        this.viewCount = viewCount;
    }

    @Column(name = "can_sale_count")
    @JsonProperty
    public BigDecimal getCanSaleCount() {
        return canSaleCount;
    }

    public void setCanSaleCount(BigDecimal canSaleCount) {
        this.canSaleCount = canSaleCount;
    }

    @Column(length = 128, nullable = true)
    @JsonProperty
    public String getPromoStyleKey() {
        return promoStyleKey;
    }

    public void setPromoStyleKey(String promoStyleKey) {
        this.promoStyleKey = promoStyleKey;
    }

    @Column(length = 32, nullable = true)
    @JsonProperty
    public String getUndefinePricePlanRule() {
        return undefinePricePlanRule;
    }

    public void setUndefinePricePlanRule(String undefinePricePlanRule) {
        this.undefinePricePlanRule = undefinePricePlanRule;
    }

    @JsonProperty
    public BigDecimal getCostPrice() {
        return costPrice;
    }

    public void setCostPrice(BigDecimal costPrice) {
        this.costPrice = costPrice;
    }

    @Column(length = 64, nullable = true)
    @JsonProperty
    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    @Column(length = 512, nullable = true)
    @JsonProperty
    public String getSourceUrl() {
        return sourceUrl;
    }

    public void setSourceUrl(String sourceUrl) {
        this.sourceUrl = sourceUrl;
    }

    public Date getPurchaseCodeExpiredDatetime() {
        return purchaseCodeExpiredDatetime;
    }

    public void setPurchaseCodeExpiredDatetime(Date purchaseCodeExpiredDatetime) {
        this.purchaseCodeExpiredDatetime = purchaseCodeExpiredDatetime;

    }

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    public CommodityTypeEnum getCommodityType() {
        return commodityType;
    }

    public void setCommodityType(CommodityTypeEnum commodityType) {
        this.commodityType = commodityType;
    }

    @Column(length = 4000)
    public String getTimelines() {
        return timelines;
    }

    public void setTimelines(String timelines) {
        this.timelines = timelines;
    }

    @Column(precision = 18, scale = 2)
    public BigDecimal getCommissionRate() {
        return commissionRate;
    }

    public void setCommissionRate(BigDecimal commissionRate) {
        this.commissionRate = commissionRate;
    }

    @Enumerated(EnumType.STRING)
    @Column(length = 16)
    @JsonProperty
    public PurchaseCodeExpireRuleEnum getPurchaseCodeExpireRule() {
        return purchaseCodeExpireRule;
    }

    public void setPurchaseCodeExpireRule(PurchaseCodeExpireRuleEnum purchaseCodeExpireRule) {
        this.purchaseCodeExpireRule = purchaseCodeExpireRule;
    }

    public Integer getPurchaseCodeExpiredDays() {
        return purchaseCodeExpiredDays;
    }

    public void setPurchaseCodeExpiredDays(Integer purchaseCodeExpiredDays) {
        this.purchaseCodeExpiredDays = purchaseCodeExpiredDays;
    }

    @ManyToOne(optional = true, cascade = CascadeType.DETACH)
    @JoinColumn(name = "Category_SID", nullable = true)
    @JsonProperty
    @NotAudited
    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    @ManyToOne(optional = true, cascade = CascadeType.DETACH)
    @JoinColumn(name = "Partner_SID", nullable = true)
    @JsonProperty
    @NotAudited
    public Partner getPartner() {
        return partner;
    }

    @SkipParamBind
    public void setPartner(Partner partner) {
        this.partner = partner;
    }

    @ManyToOne(optional = true, cascade = CascadeType.DETACH)
    @JoinColumn(name = "provider_sid", nullable = true)
    @JsonProperty
    @NotAudited
    public Partner getProvider() {
        return provider;
    }

    public void setProvider(Partner provider) {
        this.provider = provider;
    }


    @Column(length = 128, name = "commodity_barcode")
    @JsonProperty
    public String getBarcode() {
        return barcode;
    }

    public void setBarcode(String barcode) {
        this.barcode = barcode;
    }

    @Column(length = 64)
    public String getSourceUid() {
        return sourceUid;
    }

    public void setSourceUid(String sourceUid) {
        this.sourceUid = sourceUid;
    }

    public Boolean getGenPurchaseCodeFlag() {
        return genPurchaseCodeFlag;
    }

    public void setGenPurchaseCodeFlag(Boolean genPurchaseCodeFlag) {
        this.genPurchaseCodeFlag = genPurchaseCodeFlag;
    }

    public Long getLoveCount() {
        return loveCount;
    }

    public void setLoveCount(Long loveCount) {
        this.loveCount = loveCount;
    }

    public Integer getDiyBoxLength() {
        return diyBoxLength;
    }

    public void setDiyBoxLength(Integer diyBoxLength) {
        this.diyBoxLength = diyBoxLength;
    }

    public Integer getDiyBoxWidth() {
        return diyBoxWidth;
    }

    public void setDiyBoxWidth(Integer diyBoxWidth) {
        this.diyBoxWidth = diyBoxWidth;
    }

    public Integer getDiyBoxHeight() {
        return diyBoxHeight;
    }

    public void setDiyBoxHeight(Integer diyBoxHeight) {
        this.diyBoxHeight = diyBoxHeight;
    }

    public Boolean getDiyEnableDesign() {
        return diyEnableDesign;
    }

    public void setDiyEnableDesign(Boolean diyEnableDesign) {
        this.diyEnableDesign = diyEnableDesign;
    }

    public String getDiyMaxSettleCount() {
        return diyMaxSettleCount;
    }

    public void setDiyMaxSettleCount(String diyMaxSettleCount) {
        this.diyMaxSettleCount = diyMaxSettleCount;
    }

    @Column(length = 64, nullable = true)
    public String getDiyShowPic() {
        return diyShowPic;
    }

    public void setDiyShowPic(String diyShowPic) {
        this.diyShowPic = diyShowPic;
    }

    @Column(length = 64, nullable = true)
    public String getPrompt() {
        return prompt;
    }

    public void setPrompt(String prompt) {
        this.prompt = prompt;
    }

    @Column(precision = 18, scale = 2, nullable = true)
    public BigDecimal getVipPrice() {
        return vipPrice;
    }

    public void setVipPrice(BigDecimal vipPrice) {
        this.vipPrice = vipPrice;
    }

    @Column(nullable = false)
    public Integer getCustomerValueLimited() {
        return customerValueLimited;
    }

    public void setCustomerValueLimited(Integer customerValueLimited) {
        this.customerValueLimited = customerValueLimited;
    }

    @Column(precision = 18, scale = 2)
    @JsonProperty
    public BigDecimal getPurchasingTotalQuantity() {
        return purchasingTotalQuantity;
    }

    public void setPurchasingTotalQuantity(BigDecimal purchasingTotalQuantity) {
        this.purchasingTotalQuantity = purchasingTotalQuantity;
    }

    @Column(name = "daily_sold_count", precision = 18, scale = 2, nullable = false)
    @JsonProperty
    public BigDecimal getDailySoldCount() {
        return dailySoldCount;
    }

    public void setDailySoldCount(BigDecimal dailySoldCount) {
        this.dailySoldCount = dailySoldCount;
    }

    @Column(name = "daily_user_can_buy", nullable = false)
    @JsonProperty
    public Integer getDailyUserCanBuy() {
        return dailyUserCanBuy;
    }

    public void setDailyUserCanBuy(Integer dailyUserCanBuy) {
        this.dailyUserCanBuy = dailyUserCanBuy;
    }

    @Column(name = "is_perfect")
    @JsonProperty
    public Boolean getPreferred() {
        return preferred;
    }

    public void setPreferred(Boolean preferred) {
        this.preferred = preferred;
    }

    @JsonSerialize(using = DateTimeJsonSerializer.class)
    @JsonProperty
    @Transient
    public Date getLastUpdateTime() {
        return this.lastModifiedDate;
    }

    @JsonProperty
    @Transient
    public String getLastUpdateBy() {
        return this.lastModifiedBy;
    }

    @Column(name = "total_real_stock_count")
    @JsonProperty
    public BigDecimal getTotalRealStockCount() {
        return totalRealStockCount;
    }

    public void setTotalRealStockCount(BigDecimal totalRealStockCount) {
        this.totalRealStockCount = totalRealStockCount;
    }

    @Column(name = "total_freezed_stock_count")
    public BigDecimal getTotalFreezedStockCount() {
        return totalFreezedStockCount;
    }

    public void setTotalFreezedStockCount(BigDecimal totalFreezedStockCount) {
        this.totalFreezedStockCount = totalFreezedStockCount;
    }

    public String getJdSku() {
        return jdSku;
    }

    public void setJdSku(String jdSku) {
        this.jdSku = jdSku;
    }

    @Column(name = "is_circle")
    @JsonProperty
    public Boolean getCircle() {
        return circle;
    }

    public void setCircle(Boolean circle) {
        this.circle = circle;
    }

    @JsonProperty
    public BigDecimal getCirclePrice() {
        return circlePrice;
    }

    public void setCirclePrice(BigDecimal circlePrice) {
        this.circlePrice = circlePrice;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    @JsonIgnore
    public List<CommodityR2Ptcategory> getCommodityR2Ptcategories() {
        return commodityR2Ptcategories;
    }

    public void setCommodityR2Ptcategories(List<CommodityR2Ptcategory> commodityR2Ptcategories) {
        this.commodityR2Ptcategories = commodityR2Ptcategories;
    }

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, optional = false, mappedBy = "commodity")
    @PrimaryKeyJoinColumn
    @JsonProperty
    @NotAudited
    public CommodityVaryPrice getCommodityVaryPrice() {
        return commodityVaryPrice;
    }

    public void setCommodityVaryPrice(CommodityVaryPrice commodityVaryPrice) {
        this.commodityVaryPrice = commodityVaryPrice;
    }

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, optional = false, mappedBy = "commodity")
    @PrimaryKeyJoinColumn
    @JsonProperty
    @NotAudited
    public VipCommodity getVipCommodity() {
        return vipCommodity;
    }

    public void setVipCommodity(VipCommodity vipCommodity) {
        this.vipCommodity = vipCommodity;
    }

    @Column(name = "weight", nullable = false)
    public BigDecimal getWeight() {
        return weight;
    }

    public void setWeight(BigDecimal weight) {
        this.weight = weight;
    }

    @JsonProperty
    public String getCircleTitle() {
        return circleTitle;
    }

    public void setCircleTitle(String circleTitle) {
        this.circleTitle = circleTitle;
    }

    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String getCircleSpecification() {
        return circleSpecification;
    }

    public void setCircleSpecification(String circleSpecification) {
        this.circleSpecification = circleSpecification;
    }

    @Column(name = "has_present")
    public Boolean getNormalPresent() {
        return normalPresent;
    }

    public void setNormalPresent(Boolean normalPresent) {
        this.normalPresent = normalPresent;
    }

    @Column(name = "circle_has_present")
    public Boolean getCirclePresent() {
        return circlePresent;
    }

    public void setCirclePresent(Boolean circlePresent) {
        this.circlePresent = circlePresent;
    }

    @JsonProperty
    public BigDecimal getCircleMinQuantity() {
        return circleMinQuantity;
    }

    public void setCircleMinQuantity(BigDecimal circleMinQuantity) {
        this.circleMinQuantity = circleMinQuantity;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommoditySaleDateCount> getCommoditySaleDateCounts() {
        return commoditySaleDateCounts;
    }

    public void setCommoditySaleDateCounts(List<CommoditySaleDateCount> commoditySaleDateCounts) {
        this.commoditySaleDateCounts = commoditySaleDateCounts;
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec;
    }

    public BigDecimal getRewardRate() {
        return rewardRate;
    }

    public void setRewardRate(BigDecimal rewardRate) {
        this.rewardRate = rewardRate;
    }

    public String getSubTitle() {
        return subTitle;
    }

    public void setSubTitle(String subTitle) {
        this.subTitle = subTitle;
    }

    public Boolean getAllowOversold() {
        return allowOversold;
    }

    public void setAllowOversold(Boolean allowOversold) {
        this.allowOversold = allowOversold;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<CommoditySkuRelation> getCommoditySkuRelations() {
        return commoditySkuRelations;
    }

    public void setCommoditySkuRelations(List<CommoditySkuRelation> commoditySkuRelations) {
        this.commoditySkuRelations = commoditySkuRelations;
    }

    @JsonProperty
    public String getErpProductId() {
        return erpProductId;
    }

    public void setErpProductId(String erpProductId) {
        this.erpProductId = erpProductId;
    }

    public String getErpSpec() {
        return erpSpec;
    }

    public void setErpSpec(String erpSpec) {
        this.erpSpec = erpSpec;
    }

    @OneToMany(mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public List<VipCommodityRate> getVipCommodityRates() {
        return vipCommodityRates;
    }

    public void setVipCommodityRates(List<VipCommodityRate> vipCommodityRates) {
        this.vipCommodityRates = vipCommodityRates;
    }

    public String getPriceCompareUrl() {
        return priceCompareUrl;
    }

    public void setPriceCompareUrl(String priceCompareUrl) {
        this.priceCompareUrl = priceCompareUrl;
    }

    public BigDecimal getPriceCompareRate() {
        return priceCompareRate;
    }

    public void setPriceCompareRate(BigDecimal priceCompareRate) {
        this.priceCompareRate = priceCompareRate;
    }

    @JsonProperty
    public BigDecimal getCoins() {
        return coins;
    }

    public void setCoins(BigDecimal coins) {
        this.coins = coins;
    }

    @JsonProperty
    public BigDecimal getBackCoins() {
        return backCoins;
    }

    public void setBackCoins(BigDecimal backCoins) {
        this.backCoins = backCoins;
    }

    public String getTaxCode() {
        return taxCode;
    }

    public void setTaxCode(String taxCode) {
        this.taxCode = taxCode;
    }

    @Enumerated(EnumType.STRING)
    @Column(name = "solr_filter_type", length = 20)
    @JsonProperty
    public SolrFilterTypeEnum getSolrFilterType() {
        return solrFilterType;
    }

    public void setSolrFilterType(SolrFilterTypeEnum solrFilterType) {
        this.solrFilterType = solrFilterType;
    }

    @Column(name = "memo", length = 200)
    @JsonProperty
    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @ManyToOne
    @JoinColumn(name = "c2c_shop_info_sid")
    @JsonProperty
    @NotAudited
    public C2cShopInfo getC2cShopInfo() {
        return c2cShopInfo;
    }

    public void setC2cShopInfo(C2cShopInfo c2cShopInfo) {
        this.c2cShopInfo = c2cShopInfo;
    }

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "commodity", cascade = CascadeType.ALL, orphanRemoval = true)
    @NotAudited
    public Set<CommodityDistributRegion> getCommodityDistributRegion() {
        return commodityDistributRegion;
    }

    public void setCommodityDistributRegion(Set<CommodityDistributRegion> commodityDistributRegion) {
        this.commodityDistributRegion = commodityDistributRegion;
    }

    @Column(name = "regions", length = 600)
    @JsonProperty
    public String getRegions() {
        if ("".equals(regions)) {
            for (CommodityDistributRegion cdr : this.commodityDistributRegion) {
                regions = regions + cdr.getRegion().getName() + ",";
            }
            if (commodityDistributRegion.size() > 0) {
                regions = regions.substring(0, regions.length() - 1);
            }
        }
        return regions;
    }

    public void setRegions(String regions) {
        this.regions = regions;
    }

    @Column(name = "region_sid", length = 600)
    @JsonProperty
    public String getRegionsId() {
        if (regionsId == null) {
            regionsId = "";
            for (CommodityDistributRegion cdr : this.commodityDistributRegion) {
                regionsId = regionsId + cdr.getRegion().getId() + ",";
            }
            if (commodityDistributRegion.size() > 0) {
                regionsId = regionsId.substring(0, regionsId.length() - 1);
            }
        }
        return regionsId;
    }

    public void setRegionsId(String regionsId) {
        this.regionsId = regionsId;
    }

    @JsonProperty
    public Boolean getCoinPageShow() {
        return coinPageShow;
    }

    public void setCoinPageShow(Boolean coinPageShow) {
        this.coinPageShow = coinPageShow;
    }
}
